#ifndef __SNAKE_H__
#define __SNAKE_H__

#include "main.h"
#include "user.h"
#include "MusicPlayer.h"

#include <iostream>
#include <fstream>
#include <cstdlib>
#include <ctime>
#include <memory> // 智能指针
#include <thread>
#include <chrono>
#include <algorithm>
#include <cstring>

//snake，贪吃蛇游戏
// 贪吃蛇  蛇身坐标用数组存储起来  然后打印数组  每个坐标判断上下左右来决定怎么走
// 蛇头用->表示  吃的用·表示  然后死亡判断用蛇头坐标和棋盘格局重叠和蛇身坐标重叠就死亡
// 棋盘直接打印一个范围内的格子  蛇身就在里面走

// 思路 :
// 蛇身设计为一个一个节点

// 方向枚举
enum class Direction 
{
    None,
    Up,
    Down,
    Left,
    Right
};

// 蛇节点类
class SnakeNode 
{
private:
    int x_;
    int y_;
    std::shared_ptr<SnakeNode> next_;
    std::shared_ptr<SnakeNode> prev_;

public:
    SnakeNode(int x, int y) : x_(x), y_(y), next_(nullptr), prev_(nullptr) {}

    // Getter和Setter方法
    // 将x和y的值设置为私有成员变量
    // 通过构造函数初始化x和y的值
    // 通过next_和prev_指针连接节点
    // 通过shared_ptr智能指针管理内存
    int getX() const { return x_; }// 通过getX和getY方法获取x和y的值
    int getY() const { return y_; }
    void setX(int x) { x_ = x; }// 通过setX和setY方法设置x和y的值
    void setY(int y) { y_ = y; }

    std::shared_ptr<SnakeNode> getNext() const { return next_; }// 通过getNext和getPrev方法获取下一个节点和上一个节点的指针
    void setNext(std::shared_ptr<SnakeNode> next) { next_ = next; }

    std::shared_ptr<SnakeNode> getPrev() const { return prev_; }// 通过setNext和setPrev方法设置下一个节点和上一个节点的指针
    void setPrev(std::shared_ptr<SnakeNode> prev) { prev_ = prev; }
};

class SnakeGame 
{
private:
    std::shared_ptr<SnakeNode> snakeHead_;
    std::vector<std::shared_ptr<SnakeNode>> bodyNodes_;
    
    
    Direction currentDirection_;
    Direction inputDirection_;
    int snakeSpeed_;        // 微秒
    int foodScore_;         // 吃食物得分
    int snakeGameScore_;    // 当前游戏得分
    int snakeLength_;       // 蛇的长度
    bool isAlive_;          // 蛇是否存活
    std::shared_ptr<SnakeNode> food_;
    int boardWidth_;
    int boardHeight_;

    // 辅助函数
    void initSnake(int startX, int startY);// 初始化蛇
    void destroySnake(); // 销毁蛇
    void moveSnake();// 移动蛇
    void autoMoveSnake();//自动移动蛇
    bool isNextFood() const;// 判断是否吃到食物
    void eatFood();// 吃食物
    std::shared_ptr<SnakeNode> createFood();// 创建食物
    bool checkCollision() const;// 检查碰撞
    void printSnake() const; // 这里假设打印功能已实现
    void endGame(int reason); // 结束游戏，reason可以是墙壁或自身

public:
    SnakeGame(int boardWidth = 32, int boardHeight = 32, int startX = 15, int startY = 15);
    ~SnakeGame() = default;

    void restart();// 重新开始游戏
    int play();// 开始游戏
    void setDirection(Direction dir);// 设置方向
    bool isGameOver() const;// 判断游戏是否结束
    int getScore() const { return snakeGameScore_; }// 获取当前分数
};

#endif // __SNAKE_H__
